package com.vf.cloud.server.mysql.server;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

import org.springframework.core.io.ClassPathResource;

import com.jfinal.kit.StrKit;
import com.vf.cloud.pass.common.constant.SoftPath;
import com.vf.cloud.pass.common.util.ProssUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Server implements Runnable {

	public static void main(String[] args) throws IOException {
		Server s = new Server();
		//s.uninstall();
		
		s.run();
		System.out.println(">>>>>>>>>>>>>>>>>>>");
		s.isRunning();
//		if() {
//			System.err.println("卸载成功.");
//		}

	}

	
	//vfcloud@2022
	
	private boolean isRun = false;

	@Override
	public void run() {
		try {
			isRun=false;
			String initialize_Server = String.format(
					"%s/mysql/bin/mysqld --defaults-file=%s/mysql/my.ini --console --initialize-insecure  ",
					SoftPath.path, SoftPath.path);
			String installCmd = String.format("%s/mysql/bin/mysqld --install VFCloudMySQL", SoftPath.path);
			String startCmd = "net start VFCloudMySQL";
			int status = executeCmd("SC QUERY \"VFCloudMySQL\" ", "SC_QUERY");
			if (0 != status) {
				System.out.println("执行检测mysql是否安装命令失败，请联系管理员.");
				return;
			}
			isCmdComplete();
			if (!isSuccess) {
				System.out.println("未安装服务，开始执行安装mysql服务流程.");
				writeConfig();
				System.out.println(">>>执行初始化mysql...");
				status = executeCmd(initialize_Server, "INITIALIZE");
				if (status != 0) {
					System.out.println("执行mysql初始化命令失败，请联系管理员.");
					return;
				}
				isCmdComplete();
				if (!isSuccess) {
					System.out.println("初始化mysql失败，请联系管理员.");
					return;
				}

				System.out.println(">>>执行初始化mysql>>>成功.");
				System.out.println(">>>执行安装mysql服务...");
				status = executeCmd(installCmd, "INSTALL");
				if (status != 0) {
					System.out.println("执行安装mysql服务命令失败，请联系管理员.");
					return;
				}
				isCmdComplete();
				if (!isSuccess) {
					System.out.println("执行安装mysql服务失败，请联系管理员.");
					return;
				}
				System.out.println(">>>执行安装mysql服务>>>成功.");
				System.out.println(">>>执行启动mysql服务...");
				status = executeCmd(startCmd, "START");
				if (status != 0) {
					System.out.println("执行启动mysql服务命令失败，请联系管理员.");
					return;
				}
				isCmdComplete();
				if (!isSuccess) {
					System.out.println("执行启动mysql服务失败，请联系管理员.");
					return;
				}
				System.out.println(">>>执行安装mysql服务>>>成功.");
				
				
				System.out.println(">>>执行下载应用数据库脚本...");
				if (!createAppSQL()) {
					System.out.println("执行下载应用数据库脚本失败，请联系管理员.");
					return;
				}
				System.out.println(">>>执行下载应用数据库脚本>>>成功.");
				System.out.println(">>>执行应用数据库脚本...");
				String createAppCmd = String.format("%s/mysql/bin/mysql -u root -P23308  < %s/mysql/vfcloud.sql",
						SoftPath.path, SoftPath.path);
				status = executeCmd(createAppCmd, "CREATE_APP");
				
				System.out.println(createAppCmd);
				
				if (status != 0) {
					System.out.println("执行创建应用数据库脚本命令失败，请联系管理员.");
					return;
				}
				isCmdComplete();
				if (!isSuccess) {
					System.out.println("执行创建应用数据库失败，请联系管理员.");
					return;
				}
				new File(String.format("%s/mysql/vfcloud.sql", SoftPath.path)).delete();
				
				
				System.out.println(">>>执行初始化应用数据库脚本...");

				if (!createUserSQL()) {
					System.out.println("执行初始化应用数据库脚本失败，请联系管理员.");
					return;
				}
				String createCmd = String.format("%s/mysql/bin/mysql -u root  -P23308  < %s/mysql/creatDB.sql",
						SoftPath.path, SoftPath.path);
				status = executeCmd(createCmd, "CREATE_USER");
				if (status != 0) {
					System.out.println("执行初始化应用数据库脚本命令失败，请联系管理员.");
					return;
				}
				isCmdComplete();
				if (!isSuccess) {
					System.out.println("执行初始化应用数据库脚本失败，请联系管理员.");
					return;
				}
				new File(String.format("%s/mysql/creatDB.sql", SoftPath.path)).delete();
				
				System.out.println("数据初始化完成.");
				isRun=true;

			} else {

				String pid = ProssUtil.getPid("23308");
				if (StrKit.isBlank(pid)) {
					stop();
					boolean ss = start();
					if (ss) {
						System.out.println(">>>启动成功");
					}
					isRun=ss;
				} else {
					System.out.println(">>>已经运行");
					isRun=true;
				}
			}
		} catch (Exception e) {
			isRun=false;
		}
	}

	public boolean isRunning() {
		while (true) {
			try {
				if (isRun) {
					break;
				}
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return isRun;
	}

	private boolean isSuccess;
	/**
	 * cmd 是否完成
	 */
	private boolean isCmdComplete;

	public boolean isCmdComplete() {
		while (true) {
			try {
				if (isCmdComplete) {
					break;
				}
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		return isRun;
	}

	public boolean start() {
		String cmd = "net start VFCloudMySQL";
		try {
			int status = executeCmd(cmd, "START");
			if (0 != status) {
				return false;
			}
			isCmdComplete();
			return isSuccess;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean stop() {
		String stopCmd = "net stop VFCloudMySQL";
		try {
			int status = executeCmd(stopCmd, "STOP");
			if (0 != status) {
				return false;
			}
			isCmdComplete();
			return isSuccess;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	public boolean uninstall() {
		String stopCmd = "net stop VFCloudMySQL";
		try {
			int status = executeCmd(stopCmd, "STOP");
			if (0 != status) {
				return false;
			}
			isCmdComplete();

			String removeCmd = String.format("%s/mysql/bin/mysqld --remove VFCloudMySQL", SoftPath.path);
			status = executeCmd(removeCmd, "REMOVE");
			if (0 != status) {
				return false;
			}
			isCmdComplete();
			deleteData(new File(String.format("%s/mysql/Data", SoftPath.path)));
			return true;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return false;
	}

	void deleteData(File file) {
		for (File subFile : file.listFiles()) {
			if (subFile.isDirectory()) {
				deleteData(subFile);
			} else {
				subFile.delete();
			}
		}
		file.delete();
	}

	/**
	 * 写入配置文件
	 */
	public boolean writeConfig() {
		BufferedWriter out = null;
		try {
			String my = "[mysqld]\r\n" + "# 设置3306端口\r\n" + "port=23308\r\n" + "# 设置mysql的安装目录\r\n"
					+ "basedir=%s/mysql\r\n" + "# 设置mysql数据库的数据的存放目录\r\n" + "datadir=%s/mysql/Data\r\n"
					+ "# 允许最大连接数\r\n" + "max_connections=200\r\n" + "# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统\r\n"
					+ "max_connect_errors=10\r\n" + "# 服务端使用的字符集默认为UTF8\r\n" + "character-set-server=utf8\r\n"
					+ "# 创建新表时将使用的默认存储引擎\r\n" + "default-storage-engine=INNODB\r\n"
					+ "# 默认使用“mysql_native_password”插件认证\r\n"
					+ "default_authentication_plugin=mysql_native_password\r\n" + "[mysql]\r\n"
					+ "# 设置mysql客户端默认字符集\r\n" + "default-character-set=utf8\r\n" + "[client]\r\n"
					+ "# 设置mysql客户端连接服务端时默认使用的端口\r\n" + "port=3306\r\n" + "default-character-set=utf8\r\n" + "";
			try {
				File f = new File(String.format("%s/mysql/my.ini", SoftPath.path));
				if (f.exists()) {
					f.delete();
				}
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true)));
				out.write(String.format(my, SoftPath.path, SoftPath.path));

				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
			}
		}
		return false;
	}

	public boolean createUserSQL() {
		BufferedWriter out = null;
		try {
			String my = "use mysql;\r\n"
					+ "ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'vfcloud@2022';\r\n"
					+ "flush privileges;";
			try {
				File f = new File(String.format("%s/mysql/creatDB.sql", SoftPath.path));
				if (f.exists()) {
					f.delete();
				}
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true)));
				out.write(String.format(my, SoftPath.path, SoftPath.path));
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
			} catch (IOException e) {
			}
		}
		return false;
	}

	public boolean createAppSQL() {
		BufferedWriter out = null;
		InputStream in=null;
		BufferedReader br = null;
		try {
			try {
				File f = new File(String.format("%s/mysql/vfcloud.sql", SoftPath.path));
				if (f.exists()) {
					f.delete();
				}
				out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(f, true)));
				ClassPathResource resource = new ClassPathResource("/db/vfcloud.sql");
				in = resource.getInputStream();
				br = new BufferedReader(new InputStreamReader(in,"utf-8"));
				String line;
	            while((line = br.readLine()) != null){
	                out.write(line+" \r\n");
	            }
				out.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null)
					out.close();
				if(br!=null) br.close();
				if(in!=null) in.close();
			} catch (IOException e) {
			}
		}
		return false;
	}

	private int executeCmd(String command, String type) throws IOException {
		try {
			isCmdComplete = false;
			isSuccess = false;
			Runtime runtime = Runtime.getRuntime();
			Process process = runtime.exec("cmd /c start /b " + command);
			new Thread(
					new ConsoleThread(new BufferedReader(new InputStreamReader(process.getInputStream(), "GBK")), type))
							.start();
			return process.waitFor();
		} catch (InterruptedException e) {
		}
		return -1;
	}

	class ConsoleThread implements Runnable {
		private BufferedReader bfr = null;
		private String type;

		public ConsoleThread(BufferedReader bfr, String type) {
			this.bfr = bfr;
			this.type = type;
		}

		@Override
		public void run() {
			String line = null;
			try {
				while ((line = bfr.readLine()) != null) {
					log.info(line);
					if (StrKit.equals("SC_QUERY", type)) {
						if (!StrKit.isBlank(line) && line.contains("VFCloudMySQL")) {
							isSuccess = true;
						}
					} else if (StrKit.equals("INSTALL", type)) {
						if (!StrKit.isBlank(line) && line.contains("Service successfully installed")) {
							isSuccess = true;
						}
					} else if (StrKit.equals("START", type)) {
						if (!StrKit.isBlank(line) && line.contains("VFCloudMySQL 服务已经启动成功")) {
							isSuccess = true;
						}
					} else if (StrKit.equals("REMOVE", type)) {
						if (!StrKit.isBlank(line) && line.contains("Service successfully removed")) {
							isSuccess = true;
						}
					}

				}
				if (StrKit.equals("INITIALIZE", type)) {
					isSuccess = true;
				} else if (StrKit.equals("CREATE_USER", type)) {
					isSuccess = true;
				}
				 else if (StrKit.equals("CREATE_APP", type)) {
						isSuccess = true;
					}
					
				
				isCmdComplete = true;
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

}
